<template>
  <div class="validate-input-container pb-3">

    <input
      v-if="tag !== 'textarea'"
      class="form-control"
      :class="{ 'is-invalid': inputRef.error }"
      :value="inputRef.val"
      @blur="validateInput"
      @input="updateValue"
      v-bind="$attrs"
    />

    <textarea
      v-else
      class="form-control"
      :class="{ 'is-invalid': inputRef.error }"
      :value="inputRef.val"
      @blur="validateInput"
      @input="updateValue"
      v-bind="$attrs"
    >
    </textarea>
    
    <span v-if="inputRef.error" class="invalid-feedback">{{
      inputRef.message
    }}</span>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, reactive, onMounted } from "vue";
import { emitter } from "./ValidateForm.vue";
const emailReg = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
interface RuleProp {
  type: "required" | "email";
  message: string;
}
export type RulesProp = RuleProp[];
export type TagType = "input" | "textarea"; // 添加一个属性,联合类型
export default defineComponent({
  name: "VaildateInput",

  props: {
    rules: Array as PropType<RulesProp>,
    modelValue: String,
  
    // 添加属性，判断是哪一个节点
    tag: {
      type: String as PropType<TagType>,
      default: "input",
    },
  },

  // 禁用 Attribute继承
  inheritAttrs: false,

  setup(props, context) {
    const inputRef = reactive({
      val: props.modelValue || "",
      error: false,
      message: "",
    });

    const updateValue = (e: KeyboardEvent) => {
      const targetValue = (e.target as HTMLInputElement).value;
      inputRef.val = targetValue;
      context.emit("update:modelValue", targetValue);
    };

    const validateInput = () => {
      // 父组件传递过来的 props.type =>  required | email 提示对应的信息
      if (props.rules) {
        // every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值
        const allPassed = props.rules.every((rule) => {
          let passed = true;
          inputRef.message = rule.message;
          switch (rule.type) {
            case "required":
              passed = inputRef.val.trim() !== "";
              break;

            case "email":
              passed = emailReg.test(inputRef.val);
              break;

            default:
              break;
          }
          //  如果 到了 case "required": 不满足，直接return 显示电子邮箱为空
          return passed;
        });
        // 把错误信息 给输入框提示出来
        inputRef.error = !allPassed;
        return allPassed;
      }
      // props.rules 永远不存在
      return true;
    };
    // 将事件发射出去，其实就是把验证函数发射出去
    onMounted(() => {
      emitter.emit("form-item-created", validateInput);
    });
    return {
      inputRef,
      validateInput,
      updateValue,
    };
  },
});
</script>

<style>
</style>